﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace SoundServant.Controls
{
    /// <summary>
    /// Interaction logic for Burner.xaml
    /// </summary>
    public partial class BurnerControl : UserControl
    {
        Burner max;
        private delegate void VoidInvokeHandler();
        private delegate void BurningTrackInvokeHandler(int track);
        private delegate void FinishedInvokeHandler(TimeSpan time);
        private delegate void ProgressInvokeHandler(int percent, string message);

        public BurnerControl(Burner m)
        {
            InitializeComponent();

            max = m;
            max.QueueUpdated += new Burner.VoidEventHandler(max_QueueUpdated);

            max.Starting += new Burner.VoidEventHandler(max_Starting);
            max.WaitingForCorrectMedia += new Burner.VoidEventHandler(max_WaitingForCorrectMedia);
            max.Burning += new Burner.VoidEventHandler(max_Burning);
            max.Canceling += new Burner.VoidEventHandler(max_Canceling);
            max.Canceled += new Burner.VoidEventHandler(max_Canceled);
            max.Finishing += new Burner.VoidEventHandler(max_Finishing);
            max.Finished += new Burner.FinishedEventHandler(max_Finished);
            max.Ready += new Burner.VoidEventHandler(max_Ready);
            max.BurningTrack += new Burner.BurningTrackEventHandler(max_BurningTrack);
            max.Progress += new Burner.ProgressEventHandler(max_Progress);
        }

        void max_Progress(int percent, string message)
        {
            this.Dispatcher.Invoke(DispatcherPriority.Send, (ProgressInvokeHandler)delegate(int _percent, string _message)
            {
                BurnerProgressBar.Value = percent;
                BurnerStatusLabel.Content = message;
            }, percent, message);
        }

        void max_BurningTrack(int track)
        {
            this.Dispatcher.Invoke(DispatcherPriority.Send, (BurningTrackInvokeHandler)delegate(int _track)
            {
                StatusLabel.Content = "Burning Track " + _track + "/" + max.CurrentCD.Disc.Tracks.Count;
            }, track);
        }

        void max_Ready()
        {
            this.Dispatcher.Invoke(DispatcherPriority.Send, (VoidInvokeHandler)delegate()
            {
                StatusLabel.Content = "Ready";
                SecondaryStatusLabel.Content = "To begin burning the next CD, click [Start Next CD]";
                CancelFinishButtonLabel1.Content = "Start Next CD";
                CancelFinishButtonLabel2.Content = "start burning the next cd";
            });
        }

        void max_Finished(TimeSpan timeTaken)
        {
            this.Dispatcher.Invoke(DispatcherPriority.Send, (FinishedInvokeHandler)delegate(TimeSpan _timeTaken)
            {
                StatusLabel.Content = "CD Finished";

                string message = max.CurrentCD.Disc.Recording.AbbrvDateType + ", Disc " + max.CurrentCD.Disc.Number + " has finished burning in " + SS.ParseTimeSpan(_timeTaken);
                if (max.CurrentCD.ForWho != "")
                {
                    message += "\r\n This CD is for: " + max.CurrentCD.ForWho;
                }
                SSMessageBox.Show(message);
                BurnerProgressBar.Value = 0;
                BurnerStatusLabel.Content = "";
            }, timeTaken);
        }

        void max_Finishing()
        {
            this.Dispatcher.Invoke(DispatcherPriority.Send, (VoidInvokeHandler)delegate()
            {
                StatusLabel.Content = "Finishing CD";
            });
        }

        void max_Canceled()
        {
            this.Dispatcher.Invoke(DispatcherPriority.Send, (VoidInvokeHandler)delegate()
            {
                StatusLabel.Content = "CD Canceled";

            });
        }

        void max_Canceling()
        {
            this.Dispatcher.Invoke(DispatcherPriority.Send, (VoidInvokeHandler)delegate()
            {
                StatusLabel.Content = "Canceling CD";
            });
        }

        void max_Burning()
        {
            this.Dispatcher.Invoke(DispatcherPriority.Send, (VoidInvokeHandler)delegate()
            {
                StatusLabel.Content = "Burning";
                string forWho = "";
                if (max.CurrentCD.ForWho != "")
                {
                    forWho = " for " + max.CurrentCD.ForWho;
                }
                SecondaryStatusLabel.Content = "Disc " + max.CurrentCD.Disc.Number + " (id:" + max.CurrentCD.Disc.Id + ") of the recording made on " + max.CurrentCD.Disc.Recording.FormatedDate + " (id:" + max.CurrentCD.Disc.Recording.Id + ") is currently being burnt" + forWho;

            });
        }

        void max_WaitingForCorrectMedia()
        {
            this.Dispatcher.Invoke(DispatcherPriority.Normal, (VoidInvokeHandler)delegate()
            {
                StatusLabel.Content = "Waiting for blank CD-R";
                SecondaryStatusLabel.Content = "Please insert a blank CD-R into your CD drive, or click [Cancel CD] to cancel the current CD";
                SSMessageBox.Show("Insert Blank CD-R", "Please insert a blank CD-R to commence burning", SSMessageBoxType.Ok);

            });
        }

        void max_Starting()
        {
            this.Dispatcher.Invoke(DispatcherPriority.Send, (VoidInvokeHandler)delegate()
            {

                StatusLabel.Content = "Loading Next CD";
                SecondaryStatusLabel.Content = "To cancel the current CD, click [Cancel CD]";
                CancelFinishButtonLabel1.Content = "Cancel";
                CancelFinishButtonLabel2.Content = "the current CD";
                DateTimeLabel.Content = max.CurrentCD.Disc.Recording.FormatedDate;
                InfoLabel.Content = SS.FullMeetingType(max.CurrentCD.Disc.Recording.Type);
                if (max.CurrentCD.Disc.Recording.Title != "") InfoLabel.Content += " | " + max.CurrentCD.Disc.Recording.Title;
                InfoLabel.Content += "(" + max.CurrentCD.Disc.Recording.Discs.Count + " discs in recording. Total Length: " + SS.ParseTimeSpan(max.CurrentCD.Disc.Recording.Length) + ")";
                DiscContentControl.Content = new DiscReadOnlyControl(max.CurrentCD.Disc);
                ForWhoLabel.Content = "CD For: " + max.CurrentCD.ForWho;
            });
        }

        void max_CDAdded(CD cd)
        {
            QueueWrapPanel.Children.Add(new CDQueueControl(cd, max));
            QueueStatusLabel.Content = "CDs in Queue: " + max.Queue.Count;
        }

        void max_QueueUpdated()
        {
            this.Dispatcher.Invoke(DispatcherPriority.Send, (VoidInvokeHandler)delegate()
            {
                QueueWrapPanel.Children.Clear();

                lock (max.Queue)
                {
                    foreach (CD cd in max.Queue)
                    {
                        QueueWrapPanel.Children.Add(new CDQueueControl(cd, max));
                    }
                    QueueStatusLabel.Content = "CDs in Queue: " + max.Queue.Count;
                }
            });
        }

        private void CancelFinishButton_Click(object sender, RoutedEventArgs e)
        {
            if (max.Status == BurnerStatus.Ready)
                max.Start();
            else if (max.Status == BurnerStatus.Waiting)
                max.CancelCurrentCD();
        }
    }
}
